[アップデート] AWS AppConfig にコンテキストに基づいてフラグ値を分けることができるマルチバリアントフラグが登場したので Lambda から使ってみた
いわさです。
AWS でフィーチャーフラグを導入したい場合は AWS AppConfig を使うことが出来ます。
アプリや環境別に構成やフラグのデプロイ管理が出来るので非常に便利ではありますが、一方で複数パターンのフラグを組み合わせたい場合はその数だけフラグのパターンか環境を用意してアプリケーションで切り替えるなど、ちょっと面倒なケースがありました。
本日のアップデートで AppConfig に対するリクエストコンテキスト情報に基づいてルールベースで複数の値を切り替える仕組みが導入されました。
例えばマルチテナントで特定テナントへのみプレビュー機能を提供するとか、一定割合のトラフィックに対してのみフラグを有効化するとか、コードで頑張らずにフィーチャーフラグを管理するクラウドサービス側でうまいことやってくれというケースにも対応出来そうです。
マルチバリアントフラグの設定方法
まずは通常どおりアプリケーションと設定プロファイルを新しく作成し、機能フラグを設定していきましょう。
で、従来どおり設定プロファイル作成時にフラグを設定するのですが、実は今回のアップデートのマルチバリアントフラグはこのタイミングではまだ作成が出来ません。
なので、まだこの時点ではデフォルトのフラグ値のみを設定しておくようにしましょう。
そして作成後に機能フラグの編集を行います。
ここで初めて、バリアントという概念があり、従来の基本フラグに加えてマルチバリアントフラグとして選択が出来ることが確認出来ます。
そしてここでマルチバリアントフラグを選択すると、次のようにバリアントを複数設定出来るようになります。
最初はデフォルトのみです。
マルチバリアントフラグの時にバリアントを新しく追加しようとすると、次のようにそのバリアントを提供する条件が設定出来ます。
設定方法に最初悩むところなのですが、次のメニューにルールブループリントというテンプレートみたいなものが用意されているので、ここをベースに作成すると良いです。
今回はバリアントルールをこんな感じで設定してみました。
ルールビルダーでバリアントが適用される条件を視覚的に確認出来ます。
ゼロから作成しようとすると悩みましたが、ブループリントを選択してそこから変更する形を取っていくと始めやすいと思います。
このルールですが、ルールビルダーで視覚的に確認・設定も出来ますが、エディタで柔軟な設定も可能です。
ルール内で使える演算子などは次の公式ドキュメントにも記述されています。
ちなみにマルチバリアントフラグについては設定プロファイルの一覧上は次のような表示となります。
この画面で直接 ON/OFF が出来ないのでコンテキストメニューから編集が必要となりますので覚えておきましょう。
マルチバリアントフラグ構成後は通常と同じ流れで AppConfig 環境へデプロイしましょう。
マルチバリアントフラグの取得方法
ここまででマルチバリアントフラグを作成し環境へデプロイすることが出来ました。
続いてアプリケーションからこの機能フラグを使ってみましょう。
AppConfig のバリアントは AppConfig Agent 経由で取得することが出来ます。今回のアップデートでエージェント側もマルチバリアントに対応しているので、アップデートを行いましょう。
この記事では Lambda でバリアントを取得してみたいと思います。
Lambda レイヤーの構成して取得する
まずは基本的な AppConfig 拡張の構成を行います。
流れとしては Lambda レイヤーを構成し、アプリケーションは localhost にリクエストを送信する形となります。
後述しますが Lambda レイヤーは本日時点では ARN で直接しておきましょう。マネジメントコンソールから選択する場合は古いバージョンが選択されたためです。
リージョンごとの ARN はこちらから取得してください。
今回は Python 3.12 ランタイムを使っています。
公式ドキュメントからのほぼ引用となりますが、次のようにリクエストを送信します。URL 内にアプリケーションや環境など私の環境固有の情報が含まれています。
import urllib.request
def lambda_handler(event, context):
url = f'http://localhost:2772/applications/hoge0724config/environments/hoge0724env/configurations/hoge0724profile1?flag=hoge-flag1'
config = urllib.request.urlopen(url).read()
return config
実行してみると、デフォルトのフラグがまずは取得されましたね。
マルチバリアントのためのコンテキストを設定
マルチバリアントの取得方法はこちらの公式ドキュメントにも詳しく記載されています。
要はリクエストヘッダーでコンテキストを設定すれば良いようです。
今回であれば次のようにuserId
を渡してみます。
import urllib.request
def lambda_handler(event, context):
url = f'http://localhost:2772/applications/hoge0724config/environments/hoge0724env/configurations/hoge0724profile1?flag=hoge-flag1'
req = urllib.request.Request(url)
req.add_header('Context', 'userId=123456789012')
# config = urllib.request.urlopen(url).read()
config = urllib.request.urlopen(req).read()
return config
実行してみましょう。どうかな...
おお、コンテキスト情報がバリアントのルールに一致したため、特定バリアントが取得されました。いいですね。
ちなみにコンテキスト情報を含むが、ルールに該当しない場合は次のようにデフォルト値が取得されました。こちらも期待どおり。
Lambda レイヤーの古いバージョンでは機能しない
本日時点ではマネジメントコンソールから選択する際の AWS-AppConfig-Extension のバージョンは 104 でした。
一方で先程指定したバージョンは東京リージョンだと 119 です。
バージョン 104 でも試してみたのですが、この場合はルールに一致するコンテキストが含まれていてもデフォルト値が取得されました。
マルチバリアントが期待どおり動作しなくなるので、エージェントや Lambda レイヤーのバージョンには注意しましょう。
さいごに
本日は AWS AppConfig にコンテキストに基づいてフラグ値を分けることができるマルチバリアントフラグが登場したので、同時にアップデートされた Lambda レイヤー AWS-AppConfig-Extension を使って取得してみました。
AppConfig 良いなと思いつつ、例えばマルチテナントのプール型などの際にテナントごとの機能フラグを制御したい場合にちょっと大変だなぁと思っていたのですが、コンテキストの基づいてうまいこと動いてくれるこの機能はとても良い気がしますね。